/*
3/6-3/12 高精度算法
1）m+n   m和n是少于20000位的正整数
2）m+n   m和n的绝对值是少于20000位的整数
3）m*n    m和n的绝对值是少于2000位的整数
4)m*a     m的绝对值是少于2000位的整数,0<=a<=10^8
5)m/a  m的绝对值是少于20000位的整数,0<=a<=10^8
6)m%a  m的绝对值是少于20000位的整数,0<=a<=10^8
7)m/ n   m和n的绝对值是少于2000位的整数
8）m%n m和n的绝对值是少于2000位的整数
9) a +b  a和b是少于20000位的数（可含有小数点）
10） a *b  a和b是少于2000位的数（可含有小数点）
11）a /b  a和b是少于2000位的数（可含有小数点）
12） 构造128位的整数的加，减，乘和除
*先用这个练习一下。
思路：
1）数据输入通过字符串的方法读入；
2）使用数组模拟相应的加。每个数组的元素保存一位。（如果你想提高效率，也可以用保存几位，但是要注意溢出问题！）
详细见：文件。
*/
#include<iostream>
#include<vector>

class BigNumber
{
private:
  static const long long SimpleDigit = 16;
  static const long long  SimpleMAX = 1000000000000000;//简单的根据64/4=16,取16位十进制为单个存储的上限,便于处理
  static const long long  HalfMAX = 10000000; //半数位,用于乘法的溢出处理

  long long pointLocation; //小数点位置,表示在标记元素的后面
  //bool isFloat;   //是否使用小数点
  int minus;  //正负号
  long long digit; // 存储的位数
  std::vector<long long> num; //存放由大数分解的分片
  std::vector<int> zero;  //记录分片中的前驱0数量

public:
  void clear(); //清理数据
  void readBigInt(); //读入一个大整数
  void printBigInt(); //输出一个大整数
  void readBigFloat();
  void reverse(); //改变正负性
  void dyAdjust();//动态调整数位，删去前0
  long long SimpleAdd(long long a,long long b,long long & tempC); //处理单片加减
  BigNumber add(BigNumber & n);
  BigNumber sub(BigNumber & n)
  {

    n.reverse();
    return this->add(n);
    n.reverse();
  };

};

void BigNumber::clear() {
  //isFloat =  false;
  digit = 0;
  pointLocation = 0;
  num.clear();
}

void BigNumber::reverse()
{
  for (int i = 0; i < num.size() ; i++) {
    num[i] = num[i]*(-1);
  }
  minus*=-1;
}

void BigNumber::dyAdjust()
{
  bool reve = false;
  if(minus < 0)
  { this->reverse(); reve = true;}
  int move;
  long long lastVal,moveVal;
  long long moveNum = 0;
  for (int i = num.size()-1; i > 0; i--) {
    lastVal = 1;
    moveVal = SimpleMAX * 10;
    move = SimpleDigit;
    while (num[i]/lastVal != 0) {
      lastVal = lastVal * 10;
      moveVal = moveVal / 10 ;
      move--;
    }
    int j = zero[i];  //处理补位时原位置的前缀0
    for (; j > 0; j--) {
      lastVal = lastVal * 10;
      moveVal = moveVal / 10 ;
      move--;
    }
    //std::cout << i << ' '<< num[i] <<" " <<zero[i]<<" " << num[i-1]<<" " <<zero[i-1] <<'\n';
    moveNum = num[i-1] % moveVal;
  //  std::cout  <<moveNum  << '\n';
    num[i]+= (moveNum)*lastVal;
    num[i-1] = num[i-1]/moveVal;

    j=0;                //处理移位时的前缀0
    if(moveNum == 0)
    {
      j = move;
      zero[i] = zero[i] + j;
    }
    else
    {
      while(moveNum < moveVal/10)
      {
        j++;
        moveNum = moveNum*10;
        zero[i] = j;
      }
    }
    if(num[i-1] == 0)
    {
      zero[i-1] = zero[i-1] - j;
    }

//   std::cout << i << ' '<< num[i] <<" " <<zero[i]<<" " << num[i-1]<<" " <<zero[i-1] <<'\n';
  }
  std::vector<long long>::iterator v = num.begin();   //处理最前的0分片
  for(;v!=num.end();v++)
  {
    if((*v)!= 0) break;
  }
  if(v!=num.begin())
    num.erase(num.begin(),v);
  zero[0] = 0;
  if(reve) this->reverse();
}

void BigNumber::readBigInt()
{
  clear();
  minus = 1;
  int zeroCount = 0;
  char c = getchar();
  while(c == ' ' || c == '\n')
  {
    c = getchar();
  }

  long long temp = 0;
  if(c == '-')
  {minus = -1;c = getchar();}
  if(c == '+')
  {minus = 1;c=getchar();}
  while (c<='9' && c>='0') {
    temp =  temp * 10 + (c-'0');

    digit++;
    if(temp == 0)
    {
      zeroCount++;
    }

    if(digit % SimpleDigit  == 0)
    {
      //std::cout << zeroCount << " ～ " << temp*minus << '\n';
      zero.push_back(zeroCount);
      num.push_back(temp*minus);
      temp = 0;
      zeroCount = 0;
    }
    c = getchar();
  }

  if(temp != 0)
  {
    //  std::cout << zeroCount << " ～ " << temp*minus << '\n';
    zero.push_back(zeroCount);
    num.push_back(temp*minus);
  }else if(zeroCount != 0)
  {
      //std::cout << zeroCount << " ～ " << temp*minus << '\n';
      zero.push_back(zeroCount);
      num.push_back(temp*minus);
  }
dyAdjust();
  //std::cout << temp << '\n';
}

void BigNumber::printBigInt()
{
  if(minus<0)
  std::cout << "-" ;
  for (int i = 0; i < num.size(); i++) {
    for (int j = 0; j < zero[i]; j++) {
      std::cout << '0';
   }
    if(num[i]!=0)
    std::cout << num[i]*minus;
  }
  // std::cout <<'\n'<< digit << '\n';
}


BigNumber BigNumber::add(BigNumber  & n)
{
  bool rever = false;
  BigNumber res;
  long long tempC = 0;//分片进位
  long long tempSUM = 0; //分片和;
  int i = num.size()-1;
  int j = n.num.size()-1;
  int re;
  if(digit<n.digit)
  {
    res = n;
    re = j;
    if(n.minus<0 && minus > 0)
    {
      res.reverse();
      this->reverse();
      n.reverse();
      rever = true;
    }
  }
  else
  {
    res = *this;
    re = i;
    if(minus<0 && n.minus > 0)
    {
      res.reverse();
      this->reverse();
      n.reverse();
      rever = true;
    }
  }
  //  res.printBigInt();
  for (; j>=0 && i >=0 ; re--,i--,j--) {
    res.num[re] = SimpleAdd(num[i],n.num[j],tempC);
  }
  if (re >= 0 ) {
    while (tempC != 0 && re >= 0) {
      res.num[re] = SimpleAdd(res.num[re],0,tempC);
      re--;
    }
  }
  if(tempC != 0)
  {
    res.num.insert(res.num.begin(),tempC);
    res.digit++;
  }

  if(rever)
  {
    res.reverse();
    reverse();
    n.reverse();
  }

//  res.dyAdjust();
  return res;


}
long long BigNumber::SimpleAdd(long long a,long long b,long long & tempC)
{
  //  std::cout << a<<" " << b << " "<< tempSUM << '\n';
  long long result;
  long long tempSUM = a+b+tempC;
  std::cout << a<<" " << b << " "<< tempSUM << '\n';
  if(a>=0&&b>=0 || a<=0&&b<=0 || tempSUM >= 0)
  {
    tempC = tempSUM/(SimpleMAX*10);
    result = tempSUM % (SimpleMAX*10);
  }
  else //if(tempSUM < 0)
  {
     tempSUM = a+SimpleMAX*10 + b +tempC;
     tempC = -1;
     result = tempSUM;
  }
  return result;
}

int  main(void) {
  BigNumber a,b,c;
  b.readBigInt();
  a.readBigInt();
 c = b.add(a);
  //a.printBigInt();
  //b.printBigInt();
  c.printBigInt();
  return 0;
}
